[imx6ull]I2C协议

您所在的位置:网站首页 imx6ull pcb [imx6ull]I2C协议

[imx6ull]I2C协议

2023-03-31 17:21| 来源: 网络整理| 查看: 265

文章目录 一、I2C协议1.I2C物理层2.I2C协议层①起始位②I2C读写地址③I2C应答信号④数据位收发⑤总线速率⑥主机发送数据流程⑦主机接收数据流程 二、I2C接口使能三、SHT20采样测试1.硬件连接2.测试代码3.Makefile4.运行测试

一、I2C协议

I2C Bus(IIC,Inter-Integrated Circuit Bus) 是由Philips公司(现被NXP 收购)推出的一种在电子通信控制领域常用的通信协议。它由时钟线(SCL)和数据线(SDA)两根线构成通信线路,利用上拉电阻将它们拉成高电平(表示总线空闲), 其典型的电压准位为+3.3V或+5V,具有电路简单、连接线少、控制简单、通信速率高等优点。

1.I2C物理层

在这里插入图片描述

I2C 总线是一种主从结构(Master/Slave)总线,I2C 总线上的每一个设备都可以作为主设备或者从设备,但一个总线上一般只有一个主设备,可以带多个从设备。主设备用来产生允许传输的时钟信号,并初始化总线的数据传输,所以主设备通常是CPU;而从设备只能被动响应主设备发起的通信请求,所以各种I2C 接口芯片将作为从设备使用。每个连接到总线的设备都有一个独立的设备地址,主机可以利用这个地址进行不同设备之间的访问。其中地址是一个七位或十位的数字。具有三种传输模式:标准模式传输速率为100kbit/s,快速模式为400kbit/s, 高速模式下可达 3.4Mbit/s,但目前大多I2C设备尚不支持高速模式。连接到相同总线的IC数量受到总线的最大电容400pF限制。 2.I2C协议层

在I2C总线上每一位数据都由一个同步时钟没冲所对应,也就是在SCL串行时钟的配合下,数据在SDA上从高位向低位一次串行传送每一位数据。I2C通信时序图如下:

在这里插入图片描述

①起始位

I2C 总线在空闲时SDA和SCL都处于高电平状态(由上拉电阻拉成高电平),当主设备要开始一次I2C通信时就发送一个START(S)信号,这个起始位就可以告诉所有I2C 从机,主设备需要开始进行 I2C 通信了;当要结束一次 I2C 通信时,则发送一个 STOP§信号结束本次通信。

在这里插入图片描述

I2C 协议起始位:当 SCL 保持高电平时,SDA 出现一个下降沿,产生一个起始位;I2C 协议停止位:当 SCL 保持高电平时,SDA 出现一个上升沿,产生一个停止位; ②I2C读写地址

在这里插入图片描述

首先在主机发送了起始信号后,第二个时序要给出通讯的目标从机的物理地址。并且I2C总线是一种能够实现半双工通信的同步串行通信协议,从主设备的角度来看具有读/写从设备的功能。

这时候I2C的读写地址如上图所示有8位(bit),其中有7bit为物理地址,还有1bit用于表示读/写方向。所以这样的I2C从设备读写通常是一个字节,其中高7位是上面描述的物理地址,最低位用来表示读写方向(0表示写操作,1表示读操作)。

③I2C应答信号

当主机往I2C总线上传输器件的地址时,所有的从机接受到了这个地址后与自己的地址相比较,如果相同则发送一个应答ACK信号,不相同则不发送 应答信号,当主机收到了应答信号后表示建立连接成功,而未收到则表示寻址失败(可以在总线时序的第九个时钟时的电平高低进行判断)。

主/从机在之后的数据通信中,数据接收方(可能是主机也可能是从机)收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放 SDA 线控制权,将 SDA 电平拉高,由接收方控制。

若希望继续,则给出“应答(ACK, Acknowledge)”信号,即SDA 为低电平;若不希望继续,则给出“非应答(NACK,Not Acknowledge)”信号,即 SDA 为高电平; 在这里插入图片描述 ④数据位收发

主机在收到从机的应答信号之后,开始给从机发送数据。SDA 数据线上的每个字节必须是 8 位,每次传输的字节数量没有限制,每个字节发送完成之后,从机必须跟一个应答信号。

I2C 总线通信时数据位传输采用MSB(最高位优先)方式发送,其中高电平表示数据位 1,低电平表示数据位 0。当传输的数据位需要改变时(如上一个位发送的是 1,下一个位要发送 0),必须发生在 SCL 为低电平期间。即规定所有设备在SCL高时候,进行数据的获取,SCL低时候,进行数据的变化。

在这里插入图片描述

⑤总线速率

I2C 总线是一种同步、半双工、采用电平信号收发的串行总线,其速率支持:

标准模式(Standard-mode):速率高达 100kbit/s快速模式(Fast-mode):速率高达 400kbit/s快速模式+(Fast-mode Plus):速率高达 1Mbit/s。高速模式(High-speed mode):速率高达 3.4Mbit/s超快速模式(Ultra Fast-mode):速率高达 5Mbit/s (单向传输时支持) ⑥主机发送数据流程

主机在检测到总线为空闲时,发送一个启动信号“S”,开始一次通信的开始;

主机接着发送一个从设备地址,它由 7bit 物理地址和 1bit 读写控制位 R/W 组成(此时 R/W=0 写操作);

相对应的从机收到命令字节后向主机回馈应答信号 ACK(ACK=0);

主机收到从机的应答信号后开始发送第一个字节的数据;

从机收到数据后返回一个应答信号 ACK;

主机收到应答信号后再发送下一个数据字节;

主机发完最后一个字节并收到 ACK 后,向从机发送一个停止信号 P 结束本次通信并释放总线;

从机收到 P 信号后也退出与主机之间的通信;

在这里插入图片描述

⑦主机接收数据流程

主机发送启动信号后,接着发送地址字节(其中 R/W=1 读操作);

对应的从机收到地址字节后,返回一个应答信号并向主机发送数据;

主机收到数据后向从机反馈一个应答信号 ACK;

从机收到应答信号后再向主机发送下一个数据;

当主机完成接收数据后,向从机发送一个 NAK,从机收到非应答信号后便停止发送;

主机发送非应答信号后,再发送一个停止信号,释放总线结束通信;

在这里插入图片描述

二、I2C接口使能

I.MX6ull有四个I2C外设,但是我们的IGKBoard开发板只使能了两路I2C外设,如下:

I2C2 ---> 触摸屏控制器,rtc时钟,摄像头控制器 I2C1 ---> 40pin扩展口使用,由DToverlay进行开启 GPIO01_IO03 ---> I2C1_SDA GPIO01_IO03 ---> I2C1_SCL

我们需要使能I2C1,所以我们需要和之前一样修改开发板的DTOverlay配置文件,添加管脚对I2C的支持,eMMC介质的boot分区下的config.txt的路径:/run/media/mmcblk1p1/config.txt 修改如下:

# Enable I2C overlay dtoverlay_i2c1=yes

在这里插入图片描述

重启后可以在/dev下查看I2C的设备节点是否存在,或者我们可以查看/sys/bus/i2c/devices中设备文件来查看I2C驱动是否加载:

ls -l /dev/i2c-* ls /sys/bus/i2c/devices/

在这里插入图片描述 当中由于驱动是从0开始编写的,所以当中i2c-0是对饮I2C1的设备节点,而还有1开头的链接文件是I2C2下的设备。

三、SHT20采样测试 1.硬件连接

在这里插入图片描述

2.测试代码

sht20.c

/********************************************************************************* * Copyright: (C) 2023 Deng Yonghao * All rights reserved. * * Filename: sht20.c * Description: This file is SHT20 get temperature and humidity code * * Version: 1.0.0(2023年03月24日) * Author: Deng Yonghao * ChangeLog: 1, Release initial version on "2023年03月24日 20时52分18秒" * ********************************************************************************/ /* * Hardware connection: * * Sht20 Module RaspberryPi/IGKBoard * VCC 3.3V * SDA SDA * SCL SCL * GND GND */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SOFTRESET 0xFE #define TRIGGER_TEMPERATURE_NO_HOLD 0xF3 #define TRIGGER_HUMIDITY_NO_HOLD 0xF5 static inline void msleep(unsigned long ms); static inline void dump_buf(const char *prompt, uint8_t *buf, int size); int sht2x_init(char *i2c_dev); int sht2x_get_serialnumber(int fd, uint8_t *serialnumber, int size); int sht2x_get_temp_humidity(int fd, float *temp, float *rh); int main(int argc, char **argv) { int fd; float temp; float rh; uint8_t serialnumber[8]; if( argc != 2) { printf("This program used to do I2C test by sht20 temperature & humidity module.\n"); printf("Usage: %s /dev/i2c-x\n", argv[0]); return 0; } fd = sht2x_init(argv[1]); if(fd printf("SHT2x get serial number failure\n"); return 3; } if( sht2x_get_temp_humidity(fd, &temp, &rh) struct timespec cSleep; unsigned long ulTmp; cSleep.tv_sec = ms / 1000; if (cSleep.tv_sec == 0) { ulTmp = ms * 10000; cSleep.tv_nsec = ulTmp * 100; } else { cSleep.tv_nsec = 0; } nanosleep(&cSleep, 0); } /* 打印 buf值*/ static inline void dump_buf(const char *prompt, uint8_t *buf, int size) { int i; if( !buf ) { return ; } if( prompt ) { printf("%s ", prompt); } for(i=0; i uint8_t buf[4]; if( fd int fd; if( (fd=open(i2c_dev, O_RDWR)) printf("SHT2x softreset failure\n"); return -2; } return fd; } /* 获取sht20的温度湿度值 */ int sht2x_get_temp_humidity(int fd, float *temp, float *rh) { uint8_t buf[4]; if( fd uint8_t buf[4]; if( fdCC} ${APP_NAME}.c -o ${APP_NAME} clean: @rm -f ${APP_NAME} 4.运行测试

下载交叉编译后的可执行文件,并赋予它可执行权限:

在这里插入图片描述

然后运行程序,并可以向sht20传感器哈一口气,可以见得温湿度变化:

在这里插入图片描述 测试成功。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3